package joomz;

import java.util.List;
import javax.script.Bindings;

public class Action
    extends Abstract
{

    public static class Parse
        extends IllegalArgumentException
    {
        public Parse(){
            super();
        }
    }


    protected Actor actor;

    protected Direction dir;

    protected Item item;

    protected joomz.Object object;

    protected Location to;

    protected Item acquire;

    protected joomz.Object show;

    protected String response;

    protected boolean exit;


    public Action(){
        super();
    }
    public Action(String parse)
        throws Action.Parse
    {
        super();
        if (null != parse){
            parse = parse.trim();
            int idx = parse.indexOf(' ');
            if (0 < idx){
                String name = parse.substring(0,idx).trim();
                String value = parse.substring(idx+1).trim();
                if (this.setActor(name)){
                    if (this.setDir(value))
                        return;
                    else if (this.setItem(value))
                        return;
                    else if (this.setObject(value))
                        return;
                    else
                        throw new Action.Parse();
                }
                else
                    throw new Action.Parse();
            }
            else {
                if (!this.setActor(parse))
                    throw new Action.Parse();
            }
        }
        else
            throw new Action.Parse();
    }


    /**
     * Action input syntax requirement for command
     */
    public Actor getActor(){
        return this.actor;
    }
    public boolean setActor(Actor actor){
        if (null != actor){
            this.actor = actor;
            return true;
        }
        else
            return false;
    }
    public boolean setActor(String actor){
        this.actor = Actor.Set.forName(actor);
        return (null != this.actor);
    }
    public boolean hasActor(String actor){
        return (this.actor == Actor.Set.forName(actor));
    }
    /**
     * Action input syntax requirement for command argument
     */
    public Direction getDir(){
        return this.dir;
    }
    public boolean setDir(Direction dir){
        if (null != dir){
            this.dir = dir;
            return true;
        }
        else
            return false;
    }
    public boolean setDir(String dir){
        return this.setDir(Direction.Set.forName(dir));
    }
    /**
     * Action input syntax requirement for command argument
     */
    public Item getItem(){
        return this.item;
    }
    public boolean setItem(Item item){
        if (null != item){
            this.item = item;
            return true;
        }
        else
            return false;
    }
    public boolean setItem(String item){
        return this.setItem(Item.Set.forName(item));
    }
    /**
     * Action input syntax requirement for command argument
     */
    public joomz.Object getObject(){
        return this.object;
    }
    public boolean setObject(joomz.Object object){
        if (null != object){
            this.object = object;
            return true;
        }
        else
            return false;
    }
    public boolean setObject(String object){
        return this.setObject(joomz.Object.Set.forName(object));
    }
    /**
     * Object of success: location for move
     */
    public Location getTo(){
        return this.to;
    }
    public void setTo(Location to){
        this.to = to;
    }
    /**
     * Object of success: item for use
     */
    public Item getAcquire(){
        return this.acquire;
    }
    public void setAcquire(Item acquire){
        this.acquire = acquire;
    }
    /**
     * Object of success: object unhides
     */
    public joomz.Object getShow(){
        return this.show;
    }
    public void setShow(joomz.Object show){
        this.show = show;
    }
    /**
     * Object of success: talk responds
     */
    public String getResponse(){
        return this.response;
    }
    public void setResponse(String response){
        this.response = response;
    }
    /**
     * Object of action: game over
     */
    public boolean getExit(){
        return this.exit;
    }
    public boolean isExit(){
        return this.exit;
    }
    public void setExit(boolean exit){
        this.exit = exit;
    }
    /**
     * Match action input syntax requirements 'actor', 'dir',
     * 'item' or 'object'.
     */
    public boolean matches(Action pattern){
        if (this == pattern)
            return true;
        else if (null != this.actor){

            if (null != pattern.actor && this.actor.equals(pattern.actor)){

                if (null != this.dir){
                    if (null == pattern.dir || (!this.dir.equals(pattern.dir)))
                        return false;
                }
                else if (null != this.object){
                    if (null == pattern.object ||(!this.object.equals(pattern.object)))
                        return false;
                }
                else if (null != this.item){
                    if (null == pattern.item ||(!this.item.equals(pattern.item)))
                        return false;
                }
                return true;
            }
        }
        return false;
    }
    public void init(Bindings bindings){
        super.init(bindings);
    }
    public boolean isValid(){
        if (null != this.actor)
            return true;
        else
            throw new Game.Invalid("Action '"+this.getId()+"' missing ACTOR.");
    }
    public java.lang.Object invoke(){
        Actor actor = this.actor;
        if (null != actor)
            return actor.invoke();
        else
            return null;
    }

}
